import { Component, OnInit, Input, Output, forwardRef, EventEmitter, } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd/message';
import { CommonService } from '../../../../services-common/common.service';
import { StorageCommonService } from '../../xstorage-manage-services/storage-common.service';
import { StorageManageStockService } from '../../xstorage-manage-services/storage-manage-stock.service';

// 商品信息
interface goodsItem {
  goodsCode?: string | number, // 商品编码
  whId?: number | string, // 仓库
  quality?: number | string, // 品质
  number?: number | string // 预计出库数量
}

@Component({
  selector: 'sninfo-select-modal',
  templateUrl: './sninfo-select-modal.component.html',
  styleUrls: ['./sninfo-select-modal.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => SninfoSelectModalComponent),
      multi: true
    }
  ]
})
export class SninfoSelectModalComponent implements OnInit {

  @Input() allocationJudge: boolean = false; // 调拨单出库选择SN判断数量
  @Input() isHideClear: boolean = false; // 是否隐藏清空按钮(默认显示)
  @Input() goodsInfoData: goodsItem = {};
  @Input() selectedData: any = [];
  @Output() snInfoConfirm = new EventEmitter();
  @Output() snInfoClear = new EventEmitter();

  searchParams: any = {
    libraryId: '', // 库位
    snCode: '' // sn码
  };
  tableParams: any = {
    loading: false,
    tableData: [],
    page: 1,
    pageSize: 10,
    total: 0
  };
  isAppointSnVisible = false;
  onChange: any = () => {};

  warehouseOptions: any[] = []; // 仓库Option
  locationOptions: any[] = []; // 库位Option

  /**
   * ----------------------------------------------------------------
   * table check
   * ----------------------------------------------------------------
   */
  checked = false;
  indeterminate = false;
  listOfCurrentPageData: readonly any[] = [];
  setOfCheckedId = new Set<number>();
  setOfCheckedArrs: any[] = [];

  updateCheckedSet(id: number, checked: boolean): void {
    if (checked) {
      this.setOfCheckedId.add(id);

      let checkedItem = this.listOfCurrentPageData.find(item => item.id === id);
      let setIds = this.setOfCheckedArrs.map(m => m.id);
      if (!setIds.includes(id)) {
        this.setOfCheckedArrs.push(checkedItem);
      }
    } else {
      let deleteIndex = this.setOfCheckedArrs.findIndex(item => item.id === id);
      this.setOfCheckedId.delete(id);

      this.setOfCheckedArrs.splice(deleteIndex, 1);
    }
  }

  onItemChecked(id: number, checked: boolean): void {
    this.updateCheckedSet(id, checked);
    this.refreshCheckedStatus();
  }

  onAllChecked(value: boolean): void {
    // 正常可选
    const listOfCurrentPageData = this.listOfCurrentPageData.filter(item => item.state === 0);
    listOfCurrentPageData.forEach(item => this.updateCheckedSet(item.id, value));
    this.refreshCheckedStatus();
  }

  onCurrentPageDataChange($event: readonly any[]): void {
    this.listOfCurrentPageData = $event;
    this.refreshCheckedStatus();
  }

  refreshCheckedStatus(): void {
    // 正常可选
    const listOfCurrentPageData = this.listOfCurrentPageData.filter(item => item.state === 0);
    this.checked = listOfCurrentPageData.every(item => this.setOfCheckedId.has(item.id)) && listOfCurrentPageData.length > 0;
    this.indeterminate = listOfCurrentPageData.some(item => this.setOfCheckedId.has(item.id)) && !this.checked;
  }

  constructor(
    private msg: NzMessageService,
    private commonService: CommonService,
    private storageCommonService: StorageCommonService,
    private storageManageStockService: StorageManageStockService
  ) { }

  ngOnInit(): void {}

  // 查询仓库Options
  async loadWarehouseOptions() {
    let params = {
      page: 1,
      pageSize: 1000
    }
    const {code, data, message}: any = await this.storageCommonService.getWarehouseList(params);
    if (code === 0) {
      this.warehouseOptions = data.records || [];
    } else {
      this.msg.error(message);
    }
  }

  // 查询库位Options
  async loadLocationOptions() {
    let params = {
      whId: !this.commonService.isEmpty(this.goodsInfoData.whId) ? this.goodsInfoData.whId : '',
      page: 1,
      pageSize: 1000
    }
    const {code, data, message}: any = await this.storageCommonService.getLocationList(params);
    if (code === 0) {
      this.locationOptions = data.records || [];
    } else {
      this.msg.error(message);
    }
  }

  async loadTable() {
    let params = {
      ...this.searchParams,
      source: 0, // 后端区分使用
      goods: !this.commonService.isEmpty(this.goodsInfoData.goodsCode) ? this.goodsInfoData.goodsCode : '', // 商品编码
      whId: !this.commonService.isEmpty(this.goodsInfoData.whId) ? this.goodsInfoData.whId : '', // 仓库
      quality: !this.commonService.isEmpty(this.goodsInfoData.quality) ? this.goodsInfoData.quality : '', // 品质
      page: this.tableParams.page,
      pageSize: this.tableParams.pageSize
    }
    this.tableParams.loading = true;
    const {code , data, message}: any = await this.storageManageStockService.getSncodeList(params);
    this.tableParams.loading = false;
    
    if (code === 0) {
      const {records, total} = data.list || {};
      this.tableParams.tableData = records || [];
      this.tableParams.total = total || 0;
    } else {
      this.msg.error(message);
    }
  }

  searchData() {
    this.tableParams.page = 1;
    this.loadTable();
  }

  resetData() {
    for(let key in this.searchParams) {
      this.searchParams[key] = '';
    }
    this.tableParams.page = 1;
    this.loadTable();
  }

  // PageIndex Change
  onPageIndexChange(index: number) {
    this.tableParams.page = index;
    this.loadTable();
  }
  // PageSize Change
  onPageSizeChange(sizeNum: number) {
    this.tableParams.page = 1;
    this.tableParams.pageSize = sizeNum;
    this.loadTable();
  }

  handleCancel() {
    this.isAppointSnVisible = false;
    this.onChange(false);
  }

  subSelectChecked() {
    if (!this.setOfCheckedId.size) {
      this.msg.warning('请先勾选所需关联项');
      return
    }

    // 出库数量不能大于预计数量(调拨单出库处理选择SN 使用)
    if (
      this.allocationJudge &&
      this.goodsInfoData.number &&
      (this.setOfCheckedId.size > this.goodsInfoData.number)
    ) {
      this.msg.warning(`出库数量不能大于预计数量${this.goodsInfoData.number}`);
      return
    }

    let itemSns = this.setOfCheckedArrs.length ?
                  this.setOfCheckedArrs.map(item => {
                    return {
                      id: item.id,
                      libraryId: item.libraryId || '',
                      name: this.filterText(this.locationOptions, item.libraryId),
                      code: item.code || '',
                      state: item.state
                    }
                  }) : '';
    this.snInfoConfirm.emit({
      ids: [...this.setOfCheckedId],
      itemSns: itemSns ? JSON.stringify(itemSns) : '',
      selectedArrs: JSON.parse(JSON.stringify(this.setOfCheckedArrs))
    });
    this.isAppointSnVisible = false;
    this.onChange(false);
  }

  // 清空已选
  clearSelectChecked() {
    this.setOfCheckedId.clear();
    this.setOfCheckedArrs = [];

    this.snInfoClear.emit({
      ids: [],
      itemSns: '',
      selectedArrs: []
    });
    this.isAppointSnVisible = false;
    this.onChange(false);
  }

  // Filter Text
  filterText(array: Array<any>, keyVal: any) {
    let tempObjs: any = {};
    if (array.length) {
      tempObjs = array.find(item => item.id === keyVal);
    }

    return tempObjs?.name || '-';
  }

  /**
   * ng model
   * ----------------------------------------------------------------
   */

  writeValue(val: any) {
    if (val) {
      this.loadWarehouseOptions();
      this.loadLocationOptions();

      this.setOfCheckedArrs = JSON.parse(JSON.stringify(this.selectedData));
      this.setOfCheckedId = new Set(this.selectedData.map((m: any) => m.id));
      this.tableParams.page = 1;
      this.loadTable();
    }
    this.isAppointSnVisible = val;
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    // this.onTouched = fn;
  }
}
